package codeforcesbot

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

type User struct {
	User_id int64
	Nickname string
	Card string
	Sex string
	Age int32
	Area string
	Level string
	Role string
	Title string
}

type Event struct {
	Time int64
	Self_id int64
	Post_type string
	Message_type string
	Sub_type string
	Message_id int32
	Group_id int64
	User_id int64
	Message string
	Raw_message string
	Sender User
}
const GoCqhttpServer = "http://localhost:5700"

func sendPrivateMessage(id int64, s string) (response *http.Response, err error) {
	fmt.Println(s)
	response, err = http.PostForm(GoCqhttpServer+ "/send_private_msg", url.Values{
		"user_id": {fmt.Sprint(id)},
		"message": {s},
	})
	fmt.Printf("Error: %+v\nResponse: %+v\n", err, response)
	return response, err
}

func sendGroupMessage(id int64, s string) (response *http.Response, err error) {
	fmt.Println(s)
	response, err = http.PostForm(GoCqhttpServer+ "/send_group_msg", url.Values{
		"group_id": {fmt.Sprint(id)},
		"message": {s},
	})
	fmt.Printf("Error: %+v\nResponse: %+v\n", err, response)
	return response, err
}

func ReplyMessage(e *Event, s string) (response *http.Response, err error) {
	fmt.Println(s)
	if e.Message_type == "group" {
		response, err = sendGroupMessage(e.Group_id, s)
	} else if e.Message_type == "private" {
		response, err = sendPrivateMessage(e.User_id, s)
	}
	return response, err
}

func StringToImg(s string) string {
	return fmt.Sprintf("[CQ:image,file=http://jiuli.xiaoapi.cn/i/text_img.php?text=%s]", url.PathEscape(s))
}

func CQatToQQId(s string) int64 {
	if len(s) <= 11 {
		return -1
	}
	ret, err := strconv.ParseInt(s[10:len(s)-1], 10, 64)
	if err == nil {
		return ret
	}
	return -1
}

type MessageHandler func(*Event, []string)

type Router map[string]MessageHandler

var MainRouter = make(Router)

func AddRoute(s string, m MessageHandler) {
	MainRouter[s] = m
}

func InitializeRouter() {
	AddRoute(".contest", func(e *Event, argv []string) {
		var s string
		if len(argv) >= 2 && argv[1] == "-f" {
			_, s = formatContests(getContests(), isUpcoming)
		}else{
			_, s = formatContests(getContestsCached(), isUpcoming)
		}
		ReplyMessage(e, StringToImg("即将到来的比赛:\n"+s))
	})

	AddRoute(".queue", func(e *Event, argv []string) {
		x, y := countStuckSubmissions(getRecentSubmissions())
		ReplyMessage(e, StringToImg("评测机状态: " + fmt.Sprintf("%d submissions in queue, %d submissions testing\n", x, y)))
	})

	AddRoute(".help", func(e *Event, argv []string) {
		ReplyMessage(e, StringToImg("当前支持的指令:\n.contest 查询即将到来的CF比赛;\n.kitty 获取随机猫图。\n.help 查询关于我的帮助信息；\n.latest *handle* 查询用户名为*handle*的CF帐号最近一次提交记录；\n.queue 查询CF当前评测队列状态；\n.read *text* AI朗读*text*\n .addCFHandle *handle* 将用户名为*handle*的CF帐号绑定到你的QQ号；\n.my 查询你的QQ号下绑定的CF帐号；\n.heat 查询你的CF热力值。需要提前将你的所有CF帐号绑定。"))
	})

	AddRoute(".test", func(e *Event, argv []string) {
		if len(argv) >= 2 {
			switch argv[1] {
			case "hpy":
				ReplyMessage(e, "[CQ:json,data={\"app\":\"com.tencent.miniapp\"&#44;\"desc\":\"\"&#44;\"view\":\"notification\"&#44;\"ver\":\"0.0.0.1\"&#44;\"prompt\":\"&#91;应用&#93;\"&#44;\"appID\":\"\"&#44;\"sourceName\":\"\"&#44;\"actionData\":\"\"&#44;\"actionData_A\":\"\"&#44;\"sourceUrl\":\"\"&#44;\"meta\":{\"notification\":{\"appInfo\":{\"appName\":\"全国疫情数据统计\"&#44;\"appType\":4&#44;\"appid\":1109659848&#44;\"iconUrl\":\"http://gchat.qpic.cn/gchatpic_new/719328335/-2010394141-6383A777BEB79B70B31CE250142D740F/0\"}&#44;\"data\":&#91;{\"title\":\"确诊\"&#44;\"value\":\"80932\"}&#44;{\"title\":\"今日确诊\"&#44;\"value\":\"28\"}&#44;{\"title\":\"疑似\"&#44;\"value\":\"72\"}&#44;{\"title\":\"今日疑似\"&#44;\"value\":\"5\"}&#44;{\"title\":\"治愈\"&#44;\"value\":\"60197\"}&#44;{\"title\":\"今日治愈\"&#44;\"value\":\"1513\"}&#44;{\"title\":\"死亡\"&#44;\"value\":\"3140\"}&#44;{\"title\":\"今**亡\"&#44;\"value\":\"17\"}&#93;&#44;\"title\":\"中国加油,武汉加油\"&#44;\"button\":&#91;{\"name\":\"病毒:SARS-CoV-2,其导致疾病命名COVID-19\"&#44;\"action\":\"\"}&#44;{\"name\":\"传染源:新冠肺炎的患者。无症状感染者也可能成为传染源。\"&#44;\"action\":\"\"}&#93;&#44;\"emphasis_keyword\":\"\"}}&#44;\"text\":\"\"&#44;\"sourceAd\":\"\"}]")
			case "1":
				ReplyMessage(e, "[CQ:tts,text=今天是星期一，该起床上班上学喽。]")
			case "vvvvvv":
				ReplyMessage(e, "[CQ:record,file=file:///home/hpy/Music/Rick_Astley_-_Never_Gonna_Give_You_Up.mp3]")
			default:
				for key, val := range argv {
					if key > 0 {
						ReplyMessage(e, val)
					}
				}
			}
		}

	})

	AddRoute(".kitty", func(e *Event, argv []string) {
		str := getKitty()
		if str != "" {
			ReplyMessage(e, fmt.Sprintf("[CQ:image,file=%s]", str))
		}
	})

	AddRoute(".latest", func(e *Event, argv []string) {

		if len(argv) < 2 {
			ReplyMessage(e, "ERROR PARAMETER MISSING")
			return
		}

		submissions := getUserSubmissions(argv[1], 1)
		if len(submissions) > 0 {
			str := getSubmissionJson(submissions[0])
			fmt.Println(str)
			ReplyMessage(e, str)
		} else {
			ReplyMessage(e, "ERROR: SUBMISSION NOT FOUND")
		}
	})

	AddRoute(".read", func(e *Event, argv []string) {
		if len(argv) < 2 {
			ReplyMessage(e, "[CQ:record,file=file:///home/hpy/Music/Rick_Astley_-_Never_Gonna_Give_You_Up.mp3]")
			return
		}
		ReplyMessage(e, fmt.Sprintf("[CQ:tts,text=%s]", argv[1]))
	})

	AddRoute(".jyr", func(e *Event, argv []string) {
		if rand.Intn(10) <= 2 {
			ReplyMessage(e, "[CQ:image,file=file:///home/hpy/Pictures/jyr.jpg]")
		}
	})

	AddRoute(".hpy", func(e *Event, argv []string) {
		if rand.Intn(77) <= 7 {
			ReplyMessage(e, "[CQ:image,file=file:///home/hpy/Pictures/hpy.jpg]")
		}
	})

	/*AddRoute(".sql", func(e *Event, argv []string) {
		if len(argv) < 3 {
			ReplyMessage(e, "ERROR PARAMETER NOT ENOUGH")
			return
		}
		qqid, err := strconv.ParseInt(argv[1], 10, 64)
		CheckErr(err)
		ReplyMessage(e, fmt.Sprintf("[CQ:at,qq=%v] %s", qqid, SqlInsertCFid(e.User_id, argv[1])))
	})*/

	AddRoute(".addCFHandle", func(e *Event, argv []string) {
		if len(argv) < 2 {
			ReplyMessage(e, "ERROR PARAMETER NOT ENOUGH")
			return
		}
		ReplyMessage(e, fmt.Sprintf("[CQ:at,qq=%v] %s", e.User_id, SqlInsertCFid(e.User_id, argv[1])))
	})

	AddRoute(".my", func(e *Event, argv []string) {
		str := SqlQueryHandles(e.User_id)
		rep := fmt.Sprintf("[CQ:at,qq=%v] 您绑定的Codeforces帐号：", e.User_id)
		for _, handle := range str {
			rep = rep + "\n" + handle
		}
		ReplyMessage(e, rep)
	})

	AddRoute(".heat", func(e *Event, argv []string) {
		if len(argv) <= 1 {
			ReplyMessage(e, fmt.Sprintf("[CQ:at,qq=%v] 您的Codeforces热力值高达 %v！", e.User_id, getHeatValue(SqlQueryHandles(e.User_id))))
		} else {
			qqid := CQatToQQId(argv[1])
			if qqid < 0 {
				ReplyMessage(e, "ERROR PARAMETER INVALID")
			} else {
				ReplyMessage(e, fmt.Sprintf("[CQ:at,qq=%v] 的Codeforces热力值高达 %v！", qqid, getHeatValue(SqlQueryHandles(qqid))))
			}
		}
	})
	AddRoute("[CQ:at,qq=2902971635]", func(e *Event, argv []string) {
		argvLength := len(argv)
		s := ""
		for i := 1; i < argvLength; i ++ {
			s += argv[i] + " "
		}
		sendPrivateMessage(2854201761, s);
	})
}

func MainHandler(w http.ResponseWriter, req *http.Request) {
	if req.Method == http.MethodPost {
		var e Event
		s, err := ioutil.ReadAll(req.Body)
		if err == nil {
			json.Unmarshal(s, &e)
			if e.Message != "" {
				argv := strings.Fields(e.Message)
				for _, val := range argv {
					fmt.Print("["+val+"]")
				}
				fmt.Println()
				if val, ok := MainRouter[argv[0]]; ok {
					go val(&e, argv)
				} else if e.User_id == 2854201761 {
					sendGroupMessage(779440319, e.Message)
				}
			}
		}
	}
}
/*
{"app":"com.tencent.miniapp","desc":"","view":"notification","ver":"0.0.0.1","prompt":"[应用]","appID":"","sourceName":"","actionData":"","actionData_A":"","sourceUrl":"","meta":{"notification":{"appInfo":{"appName":"全国疫情数据统计","appType":4,"appid":1109659848,"iconUrl":"http:\/\/gchat.qpic.cn\/gchatpic_new\/719328335\/-2010394141-6383A777BEB79B70B31CE250142D740F\/0"},"data":[{"title":"确诊","value":"80932"},{"title":"今日确诊","value":"28"},{"title":"疑似","value":"72"},{"title":"今日疑似","value":"5"},{"title":"治愈","value":"60197"},{"title":"今日治愈","value":"1513"},{"title":"死亡","value":"3140"},{"title":"今**亡","value":"17"}],"title":"中国加油, 武汉加油","button":[{"name":"病毒 : SARS-CoV-2, 其导致疾病命名 COVID-19","action":""},{"name":"传染源 : 新冠肺炎的患者。无症状感染者也可能成为传染源。","action":""}[,"emphasis_keyword":""}},"text":"","sourceAd":""}
 */